// 技术指标计算函数 - 保留核心
function calculateRSI(data, period) {
    if (data.length < period + 1) {
        return Array(data.length).fill(null);
    }

    const rsi = Array(period).fill(null);
    let avgGain = 0;
    let avgLoss = 0;

    // 计算初始平均值
    for (let i = 1; i <= period; i++) {
        const change = data[i].close - data[i - 1].close;
        if (change > 0) {
            avgGain += change;
        } else {
            avgLoss += Math.abs(change);
        }
    }

    avgGain /= period;
    avgLoss /= period;

    // 计算第一个RSI值
    const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
    rsi.push(100 - (100 / (1 + rs)));

    // 计算后续RSI值
    for (let i = period + 1; i < data.length; i++) {
        const change = data[i].close - data[i - 1].close;
        let gain = 0;
        let loss = 0;

        if (change > 0) {
            gain = change;
            loss = 0;
        } else {
            gain = 0;
            loss = Math.abs(change);
        }

        // 平滑计算平均值
        avgGain = (avgGain * (period - 1) + gain) / period;
        avgLoss = (avgLoss * (period - 1) + loss) / period;

        const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
        rsi.push(100 - (100 / (1 + rs)));
    }

    return rsi;
}

function calculateMACD(data, shortPeriod = 12, longPeriod = 26, signalPeriod = 9) {
    if (data.length < longPeriod + signalPeriod) {
        return {
            dif: Array(data.length).fill(null),
            dea: Array(data.length).fill(null),
            macd: Array(data.length).fill(null)
        };
    }

    // 计算短期EMA和长期EMA
    const shortEMA = calculateEMA(data, shortPeriod);
    const longEMA = calculateEMA(data, longPeriod);

    // 计算DIF
    const dif = shortEMA.map((val, i) => val !== null && longEMA[i] !== null ? val - longEMA[i] : null);

    // 计算DEA (DIF的signalPeriod日EMA)
    const dea = calculateEMA(dif.map((val, i) => ({ close: val || 0, time: data[i]?.time || 0 })), signalPeriod);

    // 计算MACD柱状图 (DIF-DEA)*2
    const macd = dif.map((val, i) => val !== null && dea[i] !== null ? (val - dea[i]) * 2 : null);

    return { dif, dea, macd };
}

function calculateEMA(data, period) {
    const ema = Array(period - 1).fill(null);
    if (data.length < period) return ema;

    // 计算SMA作为初始值
    let sum = 0;
    for (let i = 0; i < period; i++) {
        sum += data[i].close;
    }
    ema.push(sum / period);

    // 计算后续EMA值
    const multiplier = 2 / (period + 1);
    for (let i = period; i < data.length; i++) {
        ema.push((data[i].close - ema[i - 1]) * multiplier + ema[i - 1]);
    }

    return ema;
}

function calculateKDJ(data, period = 9, kPeriod = 3, dPeriod = 3) {
    if (data.length < period + dPeriod) {
        return {
            k: Array(data.length).fill(null),
            d: Array(data.length).fill(null),
            j: Array(data.length).fill(null)
        };
    }

    const kValues = [];
    const dValues = [];
    const jValues = [];

    // 计算RSV值
    for (let i = 0; i < data.length; i++) {
        if (i < period - 1) {
            kValues.push(null);
            dValues.push(null);
            jValues.push(null);
            continue;
        }

        // 找出period日内的最高价和最低价
        let high = -Infinity;
        let low = Infinity;
        for (let j = i - period + 1; j <= i; j++) {
            high = Math.max(high, data[j].high);
            low = Math.min(low, data[j].low);
        }

        const close = data[i].close;
        const rsv = (close - low) / (high - low) * 100;

        // 计算K值 (RSV的kPeriod日平滑)
        let k = rsv;
        if (kValues[i - 1] !== null) {
            k = (kValues[i - 1] * (kPeriod - 1) + rsv) / kPeriod;
        }
        kValues.push(k);

        // 计算D值 (K值的dPeriod日平滑)
        let d = k;
        if (dValues[i - 1] !== null) {
            d = (dValues[i - 1] * (dPeriod - 1) + k) / dPeriod;
        }
        dValues.push(d);

        // 计算J值
        jValues.push(3 * k - 2 * d);
    }

    return { k: kValues, d: dValues, j: jValues };
}

function calculateBollingerBands(data, period = 20, multiplier = 2) {
    if (data.length < period) {
        return {
            upper: Array(data.length).fill(null),
            middle: Array(data.length).fill(null),
            lower: Array(data.length).fill(null)
        };
    }

    const middle = calculateMA(data, period);
    const upper = [];
    const lower = [];

    // 计算标准差
    for (let i = 0; i < data.length; i++) {
        if (i < period - 1) {
            upper.push(null);
            lower.push(null);
            continue;
        }

        // 计算标准差
        let sum = 0;
        for (let j = i - period + 1; j <= i; j++) {
            sum += Math.pow(data[j].close - middle[i], 2);
        }
        const stdDev = Math.sqrt(sum / period);

        // 计算上下轨
        upper.push(middle[i] + multiplier * stdDev);
        lower.push(middle[i] - multiplier * stdDev);
    }

    return { upper, middle, lower };
}

function calculateMA(data, period) {
  const ma = [];
  for (let i = 0; i < data.length;  i++) {
    if (i < period - 1) {
      ma.push(null);
      continue;
    }

    let sum = 0;
    for (let j = i - period + 1; j <= i; j++) {
      sum += data[j].close;
    }
    ma.push(sum  / period);
  }
  return ma;
}

// 分析核心类
class CryptoAnalyzer {
    constructor() {
        this.symbols  = ['BTCUSDT', 'ETHUSDT'];
        this.historicalData  = {};
        this.currentSignals  = {};

        this.symbols.forEach(symbol  => {
            this.historicalData[symbol]  = {};
            this.currentSignals[symbol]  = {};
        });
    }

    async startAnalysis() {
        const selectedInterval = document.getElementById('analysis-period').value;
        await this.fetchDataForAllSymbols(selectedInterval);

        for (const symbol of this.symbols)  {
            this.analyzeCurrentData(symbol,  selectedInterval);
        }

        const result = {
            currentSignals: {
                BTCUSDT: { [selectedInterval]: this.currentSignals.BTCUSDT[selectedInterval]  },
                ETHUSDT: { [selectedInterval]: this.currentSignals.ETHUSDT[selectedInterval]  }
            }
        };

        this.updateAnalysisResults(result, selectedInterval);
        return result;
    }

    async fetchDataForAllSymbols(interval) {
        const fetchPromises = [];

        for (const symbol of this.symbols)  {
            const fetchInterval = interval === '10m' ? '5m' : interval;
            fetchPromises.push(this.fetchAndProcessData(symbol,  fetchInterval, interval));
        }

        await Promise.all(fetchPromises);
    }

    async fetchAndProcessData(symbol, fetchInterval, displayInterval) {
        try {
            const limit = fetchInterval === '5m' ? 600 : 300;
            const url = `https://bnapi.bnlex.top/fapi/fapi/v1/klines?symbol=${symbol}&interval=${fetchInterval}&limit=${limit}`;
            const response = await fetch(url);

            if (!response.ok)  throw new Error(`HTTP ${response.status}`);

            const klineData = await response.json();
            const formattedData = this.formatKlineData(klineData,  displayInterval);

            this.historicalData[symbol][displayInterval] = formattedData;
            return true;
        } catch (error) {
            console.error(`获取${symbol}数据失败:`, error);
            return false;
        }
    }

    formatKlineData(klineData, displayInterval) {
        const formatted = klineData.map(item  => ({
            time: Math.floor(item[0]  / 1000),
            open: parseFloat(item[1]),
            high: parseFloat(item[2]),
            low: parseFloat(item[3]),
            close: parseFloat(item[4]),
            volume: parseFloat(item[5]),
            closeTime: item[6]
        }));

        return displayInterval === '10m' ? this.convert5mTo10m(formatted)  : formatted;
    }

    convert5mTo10m(data) {
        const merged = [];
        for (let i = 0; i < data.length  - 1; i += 2) {
            const candle1 = data[i];
            const candle2 = data[i + 1];
            merged.push({
                time: candle1.time,
                open: candle1.open,
                high: Math.max(candle1.high,  candle2.high),
                low: Math.min(candle1.low,  candle2.low),
                close: candle2.close,
                volume: candle1.volume  + candle2.volume,
                closeTime: candle2.closeTime
            });
        }
        return merged.length  > 0 ? merged : data;
    }

    analyzeCurrentData(symbol, interval) {
        const data = this.historicalData[symbol]?.[interval];
        if (!data || data.length  < 50) return;

        const lastIndex = data.length  - 1;
        const signals = this.calculateAllIndicators(data,  interval);

        // 添加支撑阻力位计算
        signals.supports  = this.getSupportResistance(data,  signals.periods);

        // 添加成交量分析
        signals.volume  = {
            current: data[lastIndex].volume,
            ma20: calculateMA(data.map(d  => ({close: d.volume})),  20)[lastIndex],
            trend: this.getTrend(data.map(d  => d.volume),  lastIndex)
        };

        // 存储结果
        this.currentSignals[symbol][interval]  = {
            ...signals,
            prediction: this.generatePrediction(signals)
        };
    }

    calculateAllIndicators(data, interval) {
        const lastIndex = data.length  - 1;

        const getPeriods = () => {
            switch(interval) {
                case '10m': return { maShort: 6, maMedium: 12, maLong: 24 };
                case '30m': return { maShort: 8, maMedium: 16, maLong: 32 };
                case '1h': return { maShort: 5, maMedium: 10, maLong: 20 };
                default: return { maShort: 5, maMedium: 10, maLong: 20 };
            }
        };

        const periods = getPeriods();

        return {
            price: data[lastIndex].close,
            maShort: calculateMA(data, periods.maShort)[lastIndex],
            maMedium: calculateMA(data, periods.maMedium)[lastIndex],
            maLong: calculateMA(data, periods.maLong)[lastIndex],
            maShortTrend: this.getTrend(calculateMA(data,  periods.maShort),  lastIndex),
            maMediumTrend: this.getTrend(calculateMA(data,  periods.maMedium),  lastIndex),
            maLongTrend: this.getTrend(calculateMA(data,  periods.maLong),  lastIndex),
            rsi: calculateRSI(data, 14)[lastIndex],
            rsiTrend: this.getTrend(calculateRSI(data,  14), lastIndex),
            macdDiff: calculateMACD(data).dif[lastIndex] - calculateMACD(data).dea[lastIndex],
            macdTrend: this.getMACDTrend(calculateMACD(data),  lastIndex),
            kdjCross: this.getKDJCross(calculateKDJ(data),  lastIndex),
            periods
        };
    }

    getSupportResistance(data, periods) {
        const lastIndex = data.length  - 1;
        const currentPrice = data[lastIndex].close;

        const maMedium = calculateMA(data, periods.maMedium)[lastIndex];
        const bb = calculateBollingerBands(data, periods.maMedium);

        return {
            support1: maMedium * 0.995,
            resistance1: maMedium * 1.005,
            support2: bb.lower[lastIndex],
            resistance2: bb.upper[lastIndex],
            support3: Math.floor(currentPrice  / 10) * 10,
            resistance3: Math.ceil(currentPrice  / 10) * 10,
            support4: this.getRecentLow(data,  24),
            resistance4: this.getRecentHigh(data,  24)
        };
    }

    getRecentLow(data, periods) {
        return Math.min(...data.slice(-periods).map(d  => d.low));
    }

    getRecentHigh(data, periods) {
        return Math.max(...data.slice(-periods).map(d  => d.high));
    }

    generatePrediction(signals) {
        const trendSignal = this.detectTrend(signals);
        const reversalSignal = this.detectReversal(signals);
        return this.combineSignals(trendSignal,  reversalSignal, signals);
    }

    detectTrend(signals) {
        const maUp = signals.maShortTrend  === 'up' && signals.maMediumTrend  === 'up';
        const maDown = signals.maShortTrend  === 'down' && signals.maMediumTrend  === 'down';

        const macdUp = ['crossUp', 'strongUp'].includes(signals.macdTrend);
        const macdDown = ['crossDown', 'strongDown'].includes(signals.macdTrend);

        const kdjUp = signals.kdjCross  === 'goldenCross';
        const kdjDown = signals.kdjCross  === 'deathCross';

        const upConditions = (maUp || macdUp) && (kdjUp || signals.rsi  < 70);
        const downConditions = (maDown || macdDown) && (kdjDown || signals.rsi  > 30);

        if (upConditions) {
            return { direction: 'up', confidence: 0.7, type: 'trend' };
        } else if (downConditions) {
            return { direction: 'down', confidence: 0.7, type: 'trend' };
        }
        return { direction: 'neutral', confidence: 0.5, type: 'trend' };
    }

    detectReversal(signals) {
        const extremeRsi = signals.rsi  > 70 || signals.rsi  < 30;
        const volumeSpike = signals.volume.current  > signals.volume.ma20  * 1.5;

        if (signals.rsi  > 70 && signals.rsiTrend  === 'down' &&
            signals.macdTrend  === 'crossDown' && volumeSpike) {
            return { direction: 'down', confidence: 0.65, type: 'reversal' };
        }

        if (signals.rsi  < 30 && signals.rsiTrend  === 'up' &&
            signals.macdTrend  === 'crossUp' && volumeSpike) {
            return { direction: 'up', confidence: 0.65, type: 'reversal' };
        }

        return null;
    }

    combineSignals(trend, reversal, signals) {
        if (trend.confidence  >= 0.7) return trend;
        if (reversal && this.volumeConfirms(reversal,  signals)) {
            return reversal;
        }
        return trend;
    }

    volumeConfirms(signal, signals) {
        const volumeTrendMatch = signal.direction  === 'up'
            ? signals.volume.trend  === 'up'
            : signals.volume.trend  === 'down';

        return volumeTrendMatch && signals.volume.current  > signals.volume.ma20;
    }

    getTrend(values, index) {
        if (index < 2 || !values[index] || !values[index-1]) return 'neutral';
        return values[index] > values[index-1] ? 'up' : 'down';
    }

    getMACDTrend(macd, index) {
        if (index < 2 || !macd.dif[index]  || !macd.dea[index])  return 'neutral';

        const dif = macd.dif[index],  dea = macd.dea[index];
        const prevDif = macd.dif[index-1],  prevDea = macd.dea[index-1];

        if (dif > dea && dif > prevDif && dea > prevDea) return 'strongUp';
        if (dif < dea && dif < prevDif && dea < prevDea) return 'strongDown';
        if (dif > dea && prevDif < prevDea) return 'crossUp';
        if (dif < dea && prevDif > prevDea) return 'crossDown';

        return 'neutral';
    }

    getKDJCross(kdj, index) {
        if (index < 2 || !kdj.k[index] || !kdj.d[index]) return 'neutral';

        const k = kdj.k[index], d = kdj.d[index];
        const prevK = kdj.k[index-1], prevD = kdj.d[index-1];

        if (k > d && prevK < prevD) return 'goldenCross';
        if (k < d && prevK > prevD) return 'deathCross';
        if (k > d) return 'above';
        if (k < d) return 'below';
        return 'neutral';
    }

    updateAnalysisResults(result, interval) {
        const btcData = result.currentSignals.BTCUSDT[interval];
        this.updateAnalysisCard('btc-card', 'BTCUSDT', btcData, interval);

        const ethData = result.currentSignals.ETHUSDT[interval];
        this.updateAnalysisCard('eth-card', 'ETHUSDT', ethData, interval);
    }

    updateAnalysisCard(cardId, symbol, signals, interval) {
        const card = document.getElementById(cardId);
        if (!card || !signals) return;

        const direction = signals.prediction.direction;
        const confidence = (signals.prediction.confidence  * 100).toFixed(1);
        const rsiValue = signals.rsi  ? signals.rsi.toFixed(2)  : 'N/A';
        const rsiLevel = this.getRSILevel(signals.rsi);
        const recommendation = this.getRecommendation(direction, signals.prediction.confidence);

        const trendColor = direction === 'up' ? 'text-green-400' : 'text-red-400';
        const trendArrow = direction === 'up' ? '↑' : '↓';

        card.innerHTML  = `
        <div class="p-4 h-full flex flex-col border rounded">
            <div class="flex justify-between items-center mb-3">
                <h2 class="text-lg font-semibold">${symbol} 行情分析</h2>
                <span class="text-xs bg-gray-700 px-2 py-1 rounded">${interval}</span>
            </div>
            
            <div class="space-y-2 flex-1">
                <div class="flex justify-between">
                    <span class="text-gray-300">趋势判断</span>
                    <span class="${trendColor} font-medium">
                        ${trendArrow} ${direction === 'up' ? '看涨' : '看跌'} 
                        <span class="text-xs">(${confidence}%)</span>
                    </span>
                </div>
                
                <div class="flex justify-between">
                    <span class="text-gray-300">RSI指数</span>
                    <span class="${this.getRSIColorClass(signals.rsi)}">   
                        ${rsiValue} <span class="text-xs">(${rsiLevel})</span>
                    </span>
                </div>
                
                <div class="flex justify-between">
                    <span class="text-gray-300">当前价格</span>
                    <span class="font-mono">$${signals.price.toFixed(2)}</span>   
                </div>
                
                <div class="mt-4 pt-3 border-t border-gray-700">
                    <div class="flex justify-between items-center">
                        <span class="text-gray-300">操作建议</span>
                        <span class="${this.getRecommendationColor(recommendation)} font-medium">
                            ${recommendation}
                        </span>
                    </div>
                </div>
            </div>
            
            <div class="mt-auto pt-4">
                <div class="grid grid-cols-2 gap-4">
                    <div class="bg-gray-700 p-2 rounded">
                        <div class="text-xs text-gray-400">主要支撑位</div>
                        <div class="text-green-400 font-mono">${signals.supports.support1.toFixed(2)}</div>  
                    </div>
                    <div class="bg-gray-700 p-2 rounded">
                        <div class="text-xs text-gray-400">主要阻力位</div>
                        <div class="text-red-400 font-mono">${signals.supports.resistance1.toFixed(2)}</div>  
                    </div>
                </div>
            </div>
        </div>`;
    }

    getRSILevel(rsiValue) {
        if (!rsiValue) return 'N/A';
        if (rsiValue > 80) return '极端超买';
        if (rsiValue > 70) return '超买';
        if (rsiValue < 20) return '极端超卖';
        if (rsiValue < 30) return '超卖';
        if (rsiValue > 60) return '强势';
        if (rsiValue < 40) return '弱势';
        return '中性';
    }

    getRSIColorClass(rsiValue) {
        if (!rsiValue) return '';
        if (rsiValue > 80) return 'text-red-500';
        if (rsiValue > 70) return 'text-red-400';
        if (rsiValue < 20) return 'text-green-500';
        if (rsiValue < 30) return 'text-green-400';
        if (rsiValue > 60) return 'text-green-300';
        if (rsiValue < 40) return 'text-red-300';
        return 'text-gray-300';
    }

    getRecommendationColor(recommendation) {
        if (recommendation.includes('看涨')) return 'text-green-400';
        if (recommendation.includes('看跌')) return 'text-red-400';
        return 'text-yellow-400';
    }

    getRecommendation(direction, confidence) {
        if (direction === 'up' && confidence > 0.7) return '强烈建议看涨';
        if (direction === 'up' && confidence > 0.5) return '建议看涨';
        if (direction === 'down' && confidence > 0.7) return '强烈建议看跌';
        if (direction === 'down' && confidence > 0.5) return '建议看跌';
        return '观望';
    }
}

// 启动分析
let isAnalyzing = false;
window.startAnalysis = async function() {
    if (isAnalyzing) return;
    isAnalyzing = true;

    try {
        const analyzer = new CryptoAnalyzer();
        await analyzer.startAnalysis();
        alert("分析成功");
    } catch (error) {
        console.error("分析出错:", error);
        alert("分析过程中出错: " + error.message);
    } finally {
        isAnalyzing = false;
    }
};
